﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;

using VSTalk.Engine.Core.XmppUtils;
using VSTalk.Model;
using VSTalk.Tools;

namespace VSTalk.Engine.Core.Feed.MessageState
{
    public class UnreadMessageCounter : IMessageConsumer, IUnreadCounter
    {
        private readonly MessageStateManager _stateManager;

        private readonly IList<IMessage> _unreadMessages = new List<IMessage>();

        private readonly IList<IMessage> _waitingMessages = new List<IMessage>();

        public UnreadMessageCounter(Interlocutor @from, MessageStateManager stateManager)
        {
            From = @from;
            _stateManager = stateManager;
        }

        public Interlocutor From { get; set; }

        public IEnumerable<IMessage> TrackingMessages
        {
            get
            {
                return _unreadMessages.Union(_waitingMessages);
            }
        }

        public int Count
        {
            get { return _unreadMessages.Count; }
        }

        public bool HasMessages
        {
            get { return Count > 0; }
        }

        public void MarkAsRead(IMessage message)
        {
            if (!_unreadMessages.Contains(message))
            {
                if (Predicate(message) && !_waitingMessages.Contains(message))
                {
                    _waitingMessages.Add(message);
                }
                return;
            }
            _stateManager.MarkAsRead(message);
            _unreadMessages.Remove(message);
            PropertyChanged.Notify(() => Count);
            PropertyChanged.Notify(() => HasMessages);
        }

        public void Consume(IMessage message)
        {
            if (_waitingMessages.Contains(message))
            {
                _waitingMessages.Remove(message);
                return;
            }
            _unreadMessages.Add(message);
            PropertyChanged.Notify(() => Count);
            PropertyChanged.Notify(() => HasMessages);
        }

        public bool Predicate(IMessage message)
        {
            return AddressPatterns.From(From)(message) &&
                   MessageUtil.IsContentMessage(message.XmppMessage);
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }
}